<template>
  <common-list>
    <common-search
      slot="search"
      @search="handleQuery"
      @reset="resetQuery"
      :otherSearch="true"
    >
      <el-form
        @submit.native.prevent
        v-model="queryParams"
        ref="queryForm"
        :inline="true"
        label-width="40px"
      >
        <el-form-item label="时间" prop="time">
          <el-date-picker
            popper-class="timePopper"
            v-model="queryParams.time"
            type="datetimerange"
            @change="dateChange"
            align="right"
            unlink-panels
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :picker-options="pickerOptions"
            :default-time="['00:00:00', '23:59:59']"
            :clearable="false"
            :editable="false"
          >
          </el-date-picker>
        </el-form-item>

        <el-form-item label="内容" prop="content">
          <el-autocomplete
            clearable
            v-model="queryParams.content"
            value-key="columnAlias"
            :fetch-suggestions="querySearch"
            :trigger-on-focus="false"
            @select="handleSelect"
            @input="handleInput"
            @keyup.enter.native="handleQuery"
          ></el-autocomplete>

          <content-tip :tipType="'log_content'"></content-tip>
        </el-form-item>
      </el-form>
      <template slot="customSearch">
        <div
          class="custom-search"
          @click="highSearch"
          :style="{ '--theme-color': systemInfo.theme }"
        >
          高级筛选
          <!--          <i class="iconfont icon-gaojishaixuan1" style="font-size: 14px"></i>-->
          <commonIcon
            iconName=" icon-gaojishaixuan1"
            iconType="icon"
            isStyle
          ></commonIcon>
        </div>
      </template>
    </common-search>

    <div class="traceabilityReport-wrap" slot="content">
      <div class="row-division-18"></div>
      <div
        style="
          width: 100%;
          height: 100%;
          background-color: #eee;
          overflow-x: hidden;
          overflow-y: scroll;
        "
      >
        <el-row :gutter="12">
          <el-col :span="24">
            <div class="common-column-wrap chart">
              <div class="common-block-wrap">
                <title-card title="实时日志" v-loading="isLoading4">
                  <div slot="content" class="chart-inside-wrap">
                    <common-table :stripe="true" :data="option">
                      <el-table-column
                        prop="hostIp"
                        label="主机IP"
                      ></el-table-column>
                      <el-table-column
                        prop="eventType"
                        label="事件类型"
                        show-overflow-tooltip
                      ></el-table-column>
                      <el-table-column
                        prop="sourceIp"
                        label="源IP"
                      ></el-table-column>
                      <el-table-column
                        prop="createtime"
                        label="采集时间"
                        show-overflow-tooltip
                      ></el-table-column>
                      <el-table-column
                        prop="content"
                        label="原始日志内容"
                        show-overflow-tooltip
                      ></el-table-column>
                      <el-table-column
                        prop="eventDate"
                        label="事件发生时间"
                        show-overflow-tooltip
                      ></el-table-column>
                      <el-table-column
                        prop="targetIp"
                        label="目标IP"
                        show-overflow-tooltip
                      ></el-table-column>

                      <el-table-column label="操作" align="center" width="50px">
                        <template slot-scope="scope">
                          <el-button type="text" @click="getInfo(scope.row)">
                            详情
                          </el-button>
                        </template>
                      </el-table-column>
                    </common-table>
                    <pagination
                      style="padding: 0 0 12px 0"
                      slot="pagination"
                      v-show="total > 0"
                      :total="total"
                      :page.sync="queryParams.pageNum"
                      :limit.sync="queryParams.pageSize"
                      @pagination="fetchList()"
                    />
                  </div>
                </title-card>
              </div>
            </div>
            <div class="row-division-18"></div>
          </el-col>
        </el-row>

        <el-row :gutter="12">
          <el-col :span="12">
            <div class="common-column-wrap top">
              <div class="common-block-wrap" style="height: 350px">
                <title-card title="日志类型排行Top5" v-loading="isLoading">
                  <base-chart
                    slot="content"
                    :option="columnOption1"
                    v-if="columnOption1.dataset.source.length"
                  ></base-chart>
                  <div class="chart-tooltip" v-else>
                    <!--                    <i class="iconfont icon-wushuju"></i>-->
                    <commonIcon
                      iconName="icon-wushuju"
                      iconType="icon"
                      :iconSize="36"
                    ></commonIcon>
                    <span class="tip-content">暂无数据</span>
                  </div>
                </title-card>
              </div>
            </div>
          </el-col>
          <!-- <div class="row-division-18"></div> -->
          <el-col :span="12">
            <div class="common-column-wrap top">
              <div class="common-block-wrap" style="height: 350px">
                <title-card title="级别分布Top5" v-loading="isLoading2">
                  <base-chart
                    slot="content"
                    :option="columnOption2"
                    v-if="columnOption2.dataset.source.length"
                  ></base-chart>
                  <div class="chart-tooltip" v-else>
                    <!--                    <i class="iconfont icon-wushuju"></i>-->
                    <commonIcon
                      iconName="icon-wushuju"
                      iconType="icon"
                      :iconSize="36"
                    ></commonIcon>
                    <span class="tip-content">暂无数据</span>
                  </div>
                </title-card>
              </div>
            </div>
          </el-col>
        </el-row>
        <div class="row-division-18"></div>
        <el-row :gutter="12">
          <el-col :span="24">
            <div class="common-column-wrap top">
              <div
                class="common-block-wrap"
                style="height: 500px; padding: 0 12px"
              >
                <title-card title="日志数量趋势" v-loading="isLoading3">
                  <base-chart
                    slot="content"
                    :option="columnOption3"
                    v-if="columnOption3.dataset.source.length"
                  ></base-chart>
                  <div class="chart-tooltip" v-else>
                    <!--                    <i class="iconfont icon-wushuju"></i>-->
                    <commonIcon
                      iconName="icon-wushuju"
                      iconType="icon"
                      :iconSize="36"
                    ></commonIcon>
                    <span class="tip-content">暂无数据</span>
                  </div>
                </title-card>
              </div>
            </div>
          </el-col>
        </el-row>
        <div class="row-division-18"></div>
      </div>
    </div>
    <common-info-dialog
      :infoLoading="infoLoading"
      :visible.sync="detailsOpen"
      @cancel="detailsOpen = false"
      :title="detailsTitle"
    >
      <Detail :detailForm="detailForm" />
    </common-info-dialog>

    <!-- 高级筛选 -->
    <advanced-filter
      ref="advancedFilter"
      @toSubmit="toSubmit"
    ></advanced-filter>
  </common-list>
</template>
<script>
import TitleChart from "@/components/EChart/TitleChart";
import { PICKOPTIONS } from "@/utils/constant";
import BaseChart from "@/components/EChart/components/BaseChart";
import {
  assetLogRelTrendData,
  assetLogRelReport,
} from "@/api/analysisCenter/analysis";
import dayjs from "dayjs";

import Detail from "./Detail/index.vue";
import commonIcon from "@/components/CommonIcon";

import {
  fetchList,
  fetchDetail,
  fetchEventTypes,
} from "@/api/analysisCenter/log";
import AdvancedFilter from "../../../log/AdvancedFilter";
import ContentTip from "../../../log/ContentTip";
import {
  generateSqlObj,
  generateSqlString,
  replaceOperator,
  setOperatorList,
} from "@/utils/util";
import { mapGetters } from "vuex";

export default {
  name: "journal",
  components: {
    TitleChart,
    AdvancedFilter,
    BaseChart,
    Detail,
    ContentTip,
    commonIcon,
  },
  props: {
    params: {
      type: String,
      default: null,
    },
  },
  data() {
    return {
      total: 0,
      isLoading: false,
      isLoading2: false,
      isLoading3: false,
      isLoading4: false,
      detailForm: {},
      infoLoading: false,
      detailsTitle: "日志详情",
      cuttentTime: "",
      pickerOptions: {
        shortcuts: PICKOPTIONS,
        //点击时，选择的是开始时间，也就是minDate
        onPick: ({ maxDate, minDate }) => {
          this.cuttentTime = minDate.getTime();
          if (maxDate) {
            //解除限制
            this.cuttentTime = "";
          }
        },
        disabledDate: (time) => {
          //是否限制的判断条件
          if (this.cuttentTime !== "") {
            const one = 30 * 24 * 3600 * 1000;
            const minTime = this.cuttentTime - one;
            const maxTime = this.cuttentTime + one;
            console.log(time.valueOf() > Date.now());

            return time.getTime() < minTime || time.getTime() > maxTime;
          }
        },
      },
      lastTime: [
        new Date().getTime() - 24 * 60 * 60 * 1000,
        new Date().getTime(),
      ],
      detailsOpen: false,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        time: [
          new Date().getTime() - 24 * 60 * 60 * 1000,
          new Date().getTime(),
        ],
        content: null,
        searchWhere: null,
      },
      columnOption2: {
        dataset: {
          source: [],
        },
        color: [
          "#E13C3A",
          "#E69137",
          "#72C141",
          "#E2BB22",
          "#39A4E1",
          "#E69137",
        ],
        tooltip: { show: true },
        grid: {
          left: 20,
          right: 20,
          bottom: 40,
          top: 20,
        },
        series: [
          {
            type: "pie",
            radius: ["50%", "75%"],
            center: ["40%", "50%"],
            labelLine: {
              show: false,
            },
            label: {
              show: false,
            },
          },
        ],
        legend: {
          show: true,
          orient: "vertical",
          align: "left",
          right: "10%",
          top: "middle",
        },
      },
      columnOption1: {
        tooltip: {
          show: true,
          formatter: function (value) {
            let tipName = value.value?.eventType;
            let tip = tipName && tipName.length > 10 ? "..." : "";
            return tipName.substring(0, 9) + tip + "：" + value.value?.count;
          },
        },
        dataset: {
          source: [],
        },
        grid: {
          left: 80,
          right: 20,
          bottom: 30,
          top: 20,
          // right: 10,
          // bottom: 50,
          // top: 40,
        },
        xAxis: {
          show: true,
          type: "category",
          axisLine: {
            show: true,
          }, // 坐标轴线
          axisTick: {
            show: false,
          }, // 坐标轴刻度
          axisLabel: {
            show: true,
            interval: 0,
            formatter: function (value) {
              let tip = value && value.length > 10 ? "..." : "";
              return value.substring(0, 9) + tip;
            },
          }, // 坐标轴标签
          splitLine: {
            show: false,
          },
        },
        yAxis: {
          type: "value",
          // splitNumber: 3,
          axisLine: {
            show: true,
          },
          axisTick: {
            show: false,
          }, // 坐标轴刻度
          axisLabel: {
            show: true,
          }, // 坐标轴标签
          splitLine: {
            show: true,
            lineStyle: {
              type: "dashed",
            },
          },
        },
        series: [
          {
            type: "bar",
            barWidth: 25,
          },
        ],
      },
      columnOption3: {
        color: ["#72C141", "#D9211F"],
        tooltip: {
          show: true,
        },
        legend: {
          show: true,
          orient: "horizontal",
          itemWidth: 22,
          itemHeight: 10,
          lineStyle: {
            type: "solid",
          },
        },
        dataset: {
          // 用 dimensions 指定了维度的顺序。直角坐标系中，
          // 默认把第一个维度映射到 X 轴上，第二个维度映射到 Y 轴上。
          // 如果不指定 dimensions，也可以通过指定 series.encode
          source: [],
        },
        grid: {
          right: 10,
          bottom: 50,
          top: 40,
        },
        xAxis: {
          show: true,
          type: "category",
          axisLine: {
            show: true,
          }, // 坐标轴线
          axisTick: {
            show: false,
          }, // 坐标轴刻度
          axisLabel: {
            show: true,
            rotate: -15,
            align: "center",
            margin: 20,
            interval: 0,
            width: 68,
            // overflow: "breakAll",
            // ellipsis: "...",
          }, // 坐标轴标签
          splitLine: {
            show: false,
          },
        },
        yAxis: {
          type: "value",
          axisLine: {
            show: true,
          },
          axisTick: {
            show: false,
          }, // 坐标轴刻度
          axisLabel: {
            show: true,
          }, // 坐标轴标签
          splitLine: {
            show: true,
            lineStyle: {
              type: "dashed",
            },
          },
        },
        series: [
          {
            type: "line",
            symbol: "circle",
            lineStyle: {
              width: 1,
              type: "dashed",
            },
          },
          {
            type: "line",
            symbol: "circle",
            lineStyle: {
              width: 1,
              type: "dashed",
            },
          },
        ],
      },
      option: [],
      originContentValue: "",
    };
  },
  watch: {},
  computed: {
    ...mapGetters(["systemInfo"]),
  },
  methods: {
    // 查询按钮操作
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.fetchList();
      this.getAssetLogRelReportType();
      this.getAssetLogRelReportLevel();
      this.getAssetLogRelTrendData();
    },
    resetQuery() {
      this.queryParams = this.$options.data().queryParams;
    },

    dateChange() {
      if (this.queryParams.time && this.queryParams.time.length > 0) {
        let time1 = this.queryParams.time[0].getTime();
        let time2 = this.queryParams.time[1].getTime();
        if (time2 - time1 > 31 * 24 * 3600 * 1000) {
          this.queryParams.time = this.lastTime;
          return;
        }

        this.lastTime = this.queryParams.time;
      }
    },

    getAssetLogRelTrendData() {
      this.isLoading3 = true;
      let date = {};
      if (this.queryParams.content) {
        date = {
          searchWhere:
            '(hostIp ="' +
            this.params +
            '")' +
            " AND " +
            this.queryParams.content,
        };
      } else {
        date = {
          searchWhere: '(hostIp ="' + this.params + '")',
        };
      }

      assetLogRelTrendData(date)
        .then((res) => {
          if (res && res.code === 200) {
            let joumaData = [];
            let alarmTrendValue = Object.values(res.data);
            Object.keys(res.data).forEach((item, index) => {
              joumaData.push({
                日期: item,
                日志数量: alarmTrendValue[index],
              });
            });
            this.columnOption3.dataset.source = joumaData;
          } else {
            this.columnOption3.dataset.source = [];
          }
        })
        .finally(() => (this.isLoading3 = false));
    },
    getAssetLogRelReportLevel() {
      this.isLoading2 = true;
      let data = {
        topCount: -1,
        statNames: "level",
      };
      data.searchWhere = this.queryParams.content;
      const time =
        '(hostIp ="' +
        this.params +
        '")' +
        " AND " +
        "createtime >=" +
        dayjs(this.queryParams.time[0]).format("YYYY-MM-DD HH:mm:ss") +
        " AND createtime <=" +
        dayjs(this.queryParams.time[1]).format("YYYY-MM-DD HH:mm:ss");
      if (data.searchWhere) {
        data.searchWhere = "(" + data.searchWhere + " AND " + time + ")";
      } else {
        data.searchWhere = "(" + time + ")";
      }
      assetLogRelReport(data)
        .then((res) => {
          if (res && res.code === 200) {
            this.columnOption2.dataset.source = res.data.reduce((r, c) => {
              r.push({
                日志级别: c.eventType,
                数量: c.count,
              });
              return r;
            }, []);
          } else {
            this.columnOption2.dataset.source = [];
          }
        })
        .finally(() => (this.isLoading2 = false));
    },
    getAssetLogRelReportType() {
      this.isLoading = true;
      let data = {
        topCount: -1,
        statNames: "eventType",
      };
      data.searchWhere = this.queryParams.content;
      const time =
        '(hostIp ="' +
        this.params +
        '")' +
        " AND " +
        "createtime >=" +
        dayjs(this.queryParams.time[0]).format("YYYY-MM-DD HH:mm:ss") +
        " AND createtime <=" +
        dayjs(this.queryParams.time[1]).format("YYYY-MM-DD HH:mm:ss");
      if (data.searchWhere) {
        data.searchWhere = "(" + data.searchWhere + " AND " + time + ")";
      } else {
        data.searchWhere = "(" + time + ")";
      }

      assetLogRelReport(data)
        .then((res) => {
          if (res && res.code == 200) {
            this.columnOption1.dataset.source = res.data;
          } else {
            this.columnOption1.dataset.source = [];
          }
        })
        .finally(() => (this.isLoading = false));
    },
    fetchList() {
      this.isLoading4 = true;
      let query = {
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize,
        searchIndex: "index-bwda-ark-analysis-*",
        startDate: dayjs(this.queryParams.time[0]).format(
          "YYYY-MM-DD HH:mm:ss"
        ),
        endDate: dayjs(this.queryParams.time[1]).format("YYYY-MM-DD HH:mm:ss"),
      };

      query.searchWhere = this.queryParams.content;
      const time =
        '(hostIp ="' +
        this.params +
        '")' +
        " AND " +
        "createtime >=" +
        dayjs(this.queryParams.time[0]).format("YYYY-MM-DD HH:mm:ss") +
        " AND createtime <=" +
        dayjs(this.queryParams.time[1]).format("YYYY-MM-DD HH:mm:ss");
      if (query.searchWhere) {
        query.searchWhere = "(" + query.searchWhere + " AND " + time + ")";
      } else {
        query.searchWhere = "(" + time + ")";
      }
      fetchList(query)
        .then((res) => {
          if (res && res.code === 200) {
            if (res.data) {
              this.total = res.data.total;
              this.option = res.data.list;
            } else {
              this.total = 0;
              this.option = [];
            }
          } else {
            this.option = [];
            this.total = 0;
            this.handleListTips(res);
          }
        })
        .finally(() => (this.isLoading4 = false));
    },
    getInfo(row) {
      this.infoLoading = true;
      fetchDetail({ indexName: row.indexName, docId: row.docId })
        .then((res) => {
          if (res && res.code === 200) {
            this.detailForm = res.data;
            this.detailsOpen = true;
          } else {
            this.$GlobalErrorConfirm("获取数据失败", res.msg);
          }
        })
        .finally(() => (this.infoLoading = false));
    },
    cancel() {
      this.detailsOpen = false;
    },
    highSearch() {
      this.$refs.advancedFilter.show();
    },
    // 高级筛选确定
    toSubmit(relations) {
      this.$refs.advancedFilter.closeDialog();
      this.queryParams.searchWhere = generateSqlObj(relations);
      this.queryParams.content = replaceOperator(generateSqlString(relations));
    },
    getEventTypes() {
      fetchEventTypes().then((res) => {
        if (res && res.code === 200) {
          this.typeMapList = res.data || [];
          this.typeMapList.forEach((item) => {
            item.value = item.columnName;
            setOperatorList(item);
          });
          this.$store.commit("log/SET_TYPE_LIST", this.typeMapList);
        } else {
          this.typeMapList = [];
        }
      });
    },
    querySearch(queryString, cb) {
      let queryArr = queryString.split(" ");
      queryString = queryArr[queryArr.length - 1];
      let typeList = this.typeMapList;
      let results = queryString
        ? typeList.filter(this.createFilter(queryString))
        : typeList;
      // 调用 callback 返回建议列表的数据
      cb(results);
    },
    createFilter(queryString) {
      return (result) => {
        return result.columnAlias
          .toLowerCase()
          .includes(queryString.toLowerCase());
      };
    },

    handleInput(val) {
      if (val) {
        let valArr = val.split(" ");
        valArr.pop();
        if (valArr && valArr.length > 0) {
          this.originContentValue = valArr.join(" ");
        }
      }
    },

    handleSelect(item) {
      this.queryParams.content = this.originContentValue
        ? this.originContentValue.concat(" " + item.value)
        : this.originContentValue.concat(item.value);
    },
  },
  mounted() {
    this.getAssetLogRelTrendData();
    this.getAssetLogRelReportLevel();
    this.getAssetLogRelReportType();
    this.fetchList();
    this.getEventTypes();
  },
};
</script>

<style scoped lang="scss">
.custom-search {
  color: var(--theme-color);
  margin-left: 20px;
  cursor: pointer;
  font-size: 14px;
}

.traceabilityReport-wrap {
  width: 100%;
  height: 100%;
  // overflow-x: hidden;
  // overflow-y: scroll;
  background-color: #eee;

  .row-division-18 {
    height: 12px;
    width: 100%;
  }

  .common-column-wrap {
    width: 100%;
    box-sizing: border-box;

    .common-block-wrap {
      height: 100%;
      width: 100%;
      box-sizing: border-box;
      background-color: #fff;
      position: relative;
      border-radius: 5px;
      overflow: hidden;

      .chart-inside-wrap {
        height: 100%;
      }
    }

    .top-relation-wrap {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
    }
  }

  .el-table {
    height: 100%;
    margin-top: 0;
  }
}

.chart-tooltip {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0.5;

  .icon-wushuju {
    font-size: 36px;
  }

  .tip-content {
    font-size: 12px;
  }
}

::v-deep .common-search-wrap {
  padding: 18px 0 0 0;
  background: #fff;
}

::v-deep .global-base-list-container {
  padding: 0;
  margin: 12px 0 0 0;
}

::v-deep .other-search {
  width: 120px !important;
}

.el-autocomplete {
  width: 300px;
}

::v-deep .list-container .global-base-list-container {
  padding-left: 18px;
}
</style>

<style lang="scss">
.timePopper.el-date-range-picker {
  .el-button--text {
    display: none;
  }
}
</style>
